package sailhero

import (
	"encoding/json"
	"errors"
	"github.com/wsw188440873/ctrl-cali/base"
	"github.com/wsw188440873/ctrl-cali/hub"
	"github.com/wsw188440873/ctrl-cali/model"
	"github.com/wsw188440873/ctrl-cali/types"
	"iot-base/common/logger"
)

type SailHero struct {
	RequestId string
	ThingId   string
	CaliId    string
	StationId string
	ModelId   string
}

func NewSaiHero(stationId, thingId, caliId, modelId, requestId string) base.CaliBase {
	return &SailHero{
		RequestId: requestId,
		ThingId:   thingId,
		CaliId:    caliId,
		StationId: stationId,
		ModelId:   modelId,
	}
}

//ZeroCali 零点校准.
func (s *SailHero) ZeroCali(data types.ZeroCali) error {
	var err error
	errCode := types.Success
	switch data.Event {
	case types.Start:
		var caliFlow = types.CaliFlowDefault[s.ModelId]
		// 获取到锁才能执行校准任务，校准只能只能一个任务执行
		isLock := hub.TaskManager.Lock(types.ZeroCalibrate)
		if isLock {
			errCode, err = NewCalibratorLogic(s.StationId, s.ThingId, s.CaliId, s.RequestId).Zero(s.ModelId, caliFlow)
			if errCode != types.Success {
				hub.TaskManager.Unlock(types.ZeroCalibrate)
			}
		} else {
			return errors.New("任务冲突，当前有任务正在运行")
		}
		s.addLog(types.ZeroCalibrate, errCode, 0, 0, 0, "", err)
	case types.End:
		hub.TaskManager.Unlock(types.ZeroCalibrate)
		taskId := hub.TaskManager.TaskId()
		errCode, err = NewCalibratorLogic(s.StationId, s.ThingId, s.CaliId, s.RequestId).CancelZero(s.ModelId)
		s.modifyLog(taskId, types.End, errCode, err)
		// 修改日志
	case types.Confirm:
		hub.TaskManager.Unlock(types.ZeroCalibrate)
		errCode, err = NewCalibratorLogic(s.StationId, s.ThingId, s.CaliId, s.RequestId).ConfirmZero(s.ModelId)
		taskId := hub.TaskManager.TaskId()
		s.modifyLog(taskId, types.Confirm, errCode, err)
		// 修改日志
	default:
		return err
	}
	if errCode != types.Success {
		return err
	} else {
		return err
	}
}
func (s *SailHero) modifyLog(taskId string, event string, code int, err error) {
	var status = SuccessStatus
	if code != types.Success {
		status = FailureStatus
	}
	var msg string
	if err != nil {
		msg = err.Error()
	}
	data := model.TaskLog{
		Status: status,
	}
	content := model.ContentJson{
		Msg:       msg,
		Code:      code,
		ModelId:   s.ModelId,
		RequestId: s.RequestId,
	}
	b, _ := json.Marshal(content)
	_ = data.Content.Scan(b)
	model.Dao.TTask.Update(taskId, data)
	logList, err := model.Dao.TTaskLog.FindByTaskID(taskId)
	if err != nil {
		logger.SLog.Errorf("[%s]  FindByTaskID err:=%v", s.RequestId, err)
	}
	modifySubTaskLog(logList[0].ID, status, err, event, []float64{})
}
func (s *SailHero) addLog(taskType string, code int, gasType int, gasNumber int, flow int, unit string, err error) {
	var status int
	// 添加日志
	if code == types.Success {
		status = 1
	} else {
		status = 2
	}
	inData := model.TaskLog{
		ID:         s.RequestId,
		StationId:  s.StationId,
		ThingId:    s.ThingId,
		TaskType:   taskType,
		PlanType:   "manual",
		Status:     status,
		ProcessNum: 1,
		CurrNum:    1,
		Msg:        types.Msg[code],
		TaskName:   "手动零气校准",
		TaskStatus: "done",
	}
	message := ""
	if err != nil {
		message = err.Error()
	}
	content := model.ContentJson{
		Msg:       message,
		Code:      code,
		RequestId: s.RequestId,
		ModelId:   s.ModelId,
		TaskType:  inData.TaskType,
		StationId: s.StationId,
	}
	b, _ := json.Marshal(content)
	_ = inData.Content.Scan(b)
	taskId, err := model.Dao.TTask.Add(inData)
	hub.TaskManager.SetTaskId(taskId)
	// 新增日志详情
	addSubTaskLog(taskId, "1", 0, s.ModelId, gasType, 0, gasNumber, flow, unit, 0, err)
}

//SpanCali 跨度校准.
func (s *SailHero) SpanCali(data types.SpanCali) error {
	var taskType string
	var err error
	errCode := types.Success
	switch data.Event {
	case types.Start:
		taskType = types.SpanCalibrate
		var caliFlow = types.CaliFlowDefault[s.ModelId]
		isLock := hub.TaskManager.Lock(types.SpanCalibrate)
		if isLock {
			errCode, err = NewCalibratorLogic(s.StationId, s.ThingId, s.CaliId, s.RequestId).Span(s.ModelId, data.Number, data.Units, caliFlow)
			s.addLog(taskType, errCode, 1, data.Number, caliFlow, data.Units, err)
			if errCode != types.Success {
				hub.TaskManager.Unlock(types.SpanCalibrate)
			}
		} else {
			return errors.New("任务冲突，当前有任务正在运行")
		}
	case types.End:
		hub.TaskManager.Unlock(types.SpanCalibrate) // 释放锁
		errCode, err = NewCalibratorLogic(s.StationId, s.ThingId, s.CaliId, s.RequestId).CancelSpan(s.ModelId, data.Number)
		taskId := hub.TaskManager.TaskId()
		s.modifyLog(taskId, types.End, errCode, err)

	case types.Confirm:
		hub.TaskManager.Unlock(types.SpanCalibrate) // 释放锁
		errCode, err = NewCalibratorLogic(s.StationId, s.ThingId, s.CaliId, s.RequestId).ConfirmSpan(s.ModelId, data.Number)
		taskId := hub.TaskManager.TaskId()
		s.modifyLog(taskId, types.Confirm, errCode, err)

	default:
		return errors.New(types.Msg[types.ParamsError])
	}
	if errCode != types.Success {
		return err
	} else {
		return err
	}
}

//CaliTask 校准任务
func (s *SailHero) CaliTask(pid, taskType, taskName string, painType string, param types.GroupTask) (string, error) {
	// 判断是否有任务正在运行
	//isRun := hub.TaskManager.IsRun()
	//if isRun == true {
	//	return "", errors.New("任务冲突，其他任务正在运行。")
	//}
	task := NewCaliTask(s.StationId, s.ThingId, s.CaliId, s.ModelId, s.RequestId)
	return task.Run(pid, taskType, taskName, painType, param)
}

//IsRunTask 检查任务是否在运行.
func (s *SailHero) IsRunTask() bool {
	return hub.TaskManager.IsRun()
}

//CancelTask 取消正在运行的任务.
func (s *SailHero) CancelTask() bool {
	hub.TaskManager.Stop()
	return true
}
